package com.bijava.api;

import com.bijava.core.Generator;
import com.bijava.entity.Column;
import com.bijava.entity.ConnectionEntity;
import com.bijava.entity.GencodePath;
import com.bijava.entity.Table;
import com.bijava.util.*;
import com.bijava.vo.*;
import com.google.gson.Gson;
import freemarker.template.TemplateException;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/gencode")
public class GencodeApi {
    @PostMapping("/getTabelAll")
    public DefaultResultBean<List<Table>> getTabelAll(GenCodedownloadFileVo genCodedownloadFileVo, HttpServletResponse response) {
        response.setHeader(" Access-Control-Allow-Origin", "*");
        ConnectionEntity connectionEntity = genCodedownloadFileVo;
        connectionEntity = findDriverClass(genCodedownloadFileVo.getSqlType(), connectionEntity);
        TableFactory tableFactory = new TableFactory(connectionEntity);
        List<Table> list = new ArrayList<>();
        try {
            list = tableFactory.getAllTables();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return Result.success(list);
    }

    @PostMapping("/getColum")
    public DefaultResultBean getColum(GenCodedownloadFileVo genCodedownloadFileVo, HttpServletResponse response) {
        response.setHeader(" Access-Control-Allow-Origin", "*");
        ConnectionEntity connectionEntity = genCodedownloadFileVo;
        connectionEntity = findDriverClass(genCodedownloadFileVo.getSqlType(), connectionEntity);
        TableFactory tableFactory = new TableFactory(connectionEntity);
        List<Column> list = tableFactory.getColumn(genCodedownloadFileVo.getTables(),connectionEntity.getJdbcUrl());
        return Result.success(list);
    }

    @PostMapping("/connectDatabase")
    public DefaultResultBean connectDatabase(GenCodedownloadFileVo genCodedownloadFileVo, HttpServletResponse response) {
        response.setHeader(" Access-Control-Allow-Origin", "*");
        try {
            ConnectionEntity connectionEntity = genCodedownloadFileVo;
            connectionEntity = findDriverClass(genCodedownloadFileVo.getSqlType(), connectionEntity);
            TableFactory tableFactory = new TableFactory(connectionEntity);
            tableFactory.getAllTables();
        } catch (SQLException e) {
            throw new BusinessException("连接失败");
        }
        return Result.success("连接成功");
    }

    public ConnectionEntity findDriverClass(String sqlType, ConnectionEntity connectionEntity) {
        if ("1".equals(sqlType)) {
            connectionEntity.setDriverClass("com.mysql.jdbc.Driver");
        } else {
            connectionEntity.setDriverClass("oracle.jdbc.driver.OracleDriver");
        }
        return connectionEntity;
    }

    @RequestMapping(value = "/genftl")
    public void genftl(String gencode, HttpServletResponse response) {
        response.setHeader(" Access-Control-Allow-Origin", "*");
        try {
            String gencode2 = Base64Util.decode(gencode);
            Gson gson = new Gson();
            Map<String, Object> map = new HashMap<>(6);
            map.putAll(gson.fromJson(gencode2, map.getClass()));
            FileOutputStream fos = null;
            String uuid = UuidUtils.uuidNoDash();
            String filedir = GencodePath.rootDir + "/" + uuid;
            String outFile = GencodePath.zipDir + "/" + uuid + ".zip";
            fos = new FileOutputStream(new File(outFile));
            CodeGeneratorUtil.BaseGen(map, "mapper.ftl", GencodePath.rootDir, filedir, map.get("fileName") + "");
            ZipUtil.toZip(filedir, fos, true);
            ZipUtil.download(outFile, response);
        } catch (IOException |TemplateException e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/downloadDemoFile")
    public void downloadDemoFile(@RequestBody FrameworkDemoVo frameworkDemoVo, HttpServletResponse response) throws Exception {
        response.setHeader(" Access-Control-Allow-Origin", "*");

        String uuid = UuidUtils.uuidNoDash();

        String filePath = GencodePath.zipDir + "/" + uuid;
        Map<String, Object> map = new HashMap<>(6);
        String project = StringUtil.stripingToCamel(frameworkDemoVo.getArtifactId());
        map.put("artifactId", frameworkDemoVo.getArtifactId());
        map.put("groupId", frameworkDemoVo.getGroupId());
        map.put("version", frameworkDemoVo.getVersion());
        map.put("description", frameworkDemoVo.getDescription());
        map.put("project", project);
        if (frameworkDemoVo.getArtifactId().contains("-")) {
            map.put("projectName", frameworkDemoVo.getArtifactId().split("-")[0]);
        } else {
            map.put("projectName", frameworkDemoVo.getArtifactId());
        }
        map.put("classProjectName", StringUtil.upperCase(project));
        List<File> genList = new ArrayList<>();

        genList.add(new File(GencodePath.frameworkFtlDir));
        new Generator(genList, filePath).generateBy(map);
        FileOutputStream fos = null;

        fos = new FileOutputStream(new File(filePath + ".zip"));

        ZipUtil.toZip(filePath, fos, true);
        ZipUtil.download(filePath + ".zip", response);
    }

    @PostMapping("/downloadOperationCode")
    public void downloadOperationCode(@RequestBody GenOperationCodeVo genCodedownloadFileVo, HttpServletResponse response) throws Exception {
        response.setHeader(" Access-Control-Allow-Origin", "*");
        ConnectionEntity connectionEntity = genCodedownloadFileVo;
        connectionEntity = findDriverClass(genCodedownloadFileVo.getSqlType(), connectionEntity);
        String uuid = UuidUtils.uuidNoDash();
        String filePath = GencodePath.zipDir + "/" + uuid;
        String table = genCodedownloadFileVo.getTables();
        String module = genCodedownloadFileVo.getModule();
        TableFactory tableFactory = new TableFactory(connectionEntity);
        List<Column> list = tableFactory.getColumn(table, connectionEntity.getJdbcUrl());
        Map<String, Object> map = new HashMap<>();
        String entityName = StringUtil.upperCase(StringUtil.camelName(table.replace(genCodedownloadFileVo.getIgnoreTablePrefix(), "")));
        map.put("keyStrategy",genCodedownloadFileVo.getKeyStrategy());
        map.put("sequenceName",genCodedownloadFileVo.getSequenceName());
        map.put("basePackege", genCodedownloadFileVo.getBasePackage());
        map.put("module", module);
        map.put("entity", entityName);
        map.put("TableName", table);
        map.put("tableComment", genCodedownloadFileVo.getTableComment());
        map.put("column", list);
        map.put("moduleName", entityName);
        map.put("columnsList", genCodedownloadFileVo.getColumnsList());
        map.put("formList", genCodedownloadFileVo.getFormList());
        map.put("queryList", genCodedownloadFileVo.getQueryList());
        String frontModuledir = genCodedownloadFileVo.getFontModule().replace("/", ".");
        map.put("frontModuledir", frontModuledir);
        String frontjsdir, frontjs;
        if(frontModuledir.contains(".")){
            frontjsdir = frontModuledir.substring(0, frontModuledir.lastIndexOf("."));
            frontjs = frontModuledir.substring(frontModuledir.lastIndexOf(".") + 1);
        }else{
            frontjsdir = frontModuledir;
            frontjs = frontModuledir;
        }
        map.put("frontjsdir", frontjsdir);
        map.put("frontjs", frontjs + ".js");
        map.put("frontModule", frontjs);
        List<File> genList = new ArrayList<>();
        genList.add(new File(GencodePath.apiFtlDir));
        new Generator(genList, filePath).generateBy(map);
        FileOutputStream fos = null;
        fos = new FileOutputStream(new File(filePath + ".zip"));
        ZipUtil.toZip(filePath, fos, true);
        ZipUtil.download(filePath + ".zip", response);
    }
}